package com.flow.asyncflow.core.utils.http;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.flow.asyncflow.core.entity.core.AsyncFlowBaseContext;
import com.flow.asyncflow.core.entity.core.AsyncFlowRequest;
import com.flow.asyncflow.core.utils.log.asyncflowlog.AsyncFlowCommon_Log;
import com.flow.asyncflow.core.utils.msg.AsyncFlowSendMsg;

import java.util.Map;

public class AsyncFlowHttpClientUtil {

    /**
     * 普通 post 请求
     *
     * @param url      地址
     * @param req      请求
     * @param resClass 返回类
     * @param <Req>    请求类型
     * @param <Res>    返回类型
     * @return 具体返回
     */
    public static <Req, Res> Res post(String url, Req req, Class<Res> resClass) {
        Res t = null;
        t = post(url, req, resClass, null);
        return t;
    }

    /**
     * 普通 post 请求
     *
     * @param url   地址
     * @param req   请求
     * @param <Req> 请求类型
     * @return 具体返回
     */
    public static <Req> String post(String url, Req req, Map<String, String> headers) {
        HttpClientRequest httpClientRequest = new HttpClientRequest();
        httpClientRequest.setUrl(url);
        httpClientRequest.setHeads(headers);
        String json;
        if (req.getClass().getName().equals("java.lang.String")) {
            json = (String) req;
        } else {
            json = JSON.toJSONString(req);
        }
        httpClientRequest.setReqJson(json);
        httpClientRequest.setHttpMethod(HttpMethod.PostJson);
        HttpClientResponse httpClientResponse = HttpClientUtil.httpResponse(httpClientRequest);
        return httpClientResponse.getBody();
    }


    /**
     * 普通 post 请求【有代理】
     *
     * @param url       地址
     * @param req       请求
     * @param resClass  返回类
     * @param <Req>     请求类型
     * @param <Res>     返回类型
     * @param proxyInfo 代理信息
     * @return 具体返回
     */
    public static <Req, Res> Res post(String url, Req req, Class<Res> resClass, ProxyInfo proxyInfo) {
        Res t = null;
        HttpClientRequest httpClientRequest = new HttpClientRequest();
        httpClientRequest.setUrl(url);
        if (proxyInfo != null) {
            httpClientRequest.setProxy(true);
            httpClientRequest.setProxyInfo(proxyInfo);
        }
        String json;
        if (req.getClass().getName().equals("java.lang.String")) {
            json = (String) req;
        } else {
            json = JSON.toJSONString(req);
        }
        httpClientRequest.setReqJson(json);
        httpClientRequest.setHttpMethod(HttpMethod.PostJson);
        HttpClientResponse httpClientResponse = HttpClientUtil.httpResponse(httpClientRequest);
        if (resClass.getName().equals("java.lang.String")) {
            t = (Res) httpClientResponse.getBody();
        } else {
            t = JSONObject.parseObject(httpClientResponse.getBody(), resClass);
        }
        return t;
    }

    /**
     * 普通get请求
     *
     * @param url      地址
     * @param req      请求键值对
     * @param resClass 返回实体
     * @param <Res>    返回实体
     * @return 返回
     */
    public static <Res> Res get(String url, Map<String, Object> req, Class<Res> resClass) {

        return get(url, req, resClass, null);
    }

    /**
     * 普通get请求
     *
     * @param url       地址
     * @param req       请求键值对
     * @param resClass  返回实体
     * @param <Res>     返回实体
     * @param proxyInfo 代理
     * @return 返回
     */
    public static <Res> Res get(String url, Map<String, Object> req, Class<Res> resClass, ProxyInfo proxyInfo) {
        Res t = null;
        HttpClientRequest httpClientRequest = new HttpClientRequest();
        httpClientRequest.setUrl(url);
        httpClientRequest.setParameter(req);
        if (proxyInfo != null) {
            httpClientRequest.setProxy(true);
            httpClientRequest.setProxyInfo(proxyInfo);
        }
        httpClientRequest.setHttpMethod(HttpMethod.Get);
        HttpClientResponse httpClientResponse = HttpClientUtil.httpResponse(httpClientRequest);
        if (resClass.getName().equals("java.lang.String")) {
            t = (Res) httpClientResponse.getBody();
        } else {
            t = JSONObject.parseObject(httpClientResponse.getBody(), resClass);
        }
        return t;
    }

    /**
     * 异步流post 请求【接口会自动记录日志到异步流中】
     *
     * @param asyncFlowBaseContext 上下文
     * @param logFileName          文件名称
     * @param LogDetailName        日志描述
     * @param url                  地址
     * @param req                  请求
     * @param resClass             返回类
     * @param <Req>                请求类型
     * @param <Res>                返回类型
     * @return 具体返回
     */
    public static <Req, Res> Res asyncFlowPost(AsyncFlowBaseContext asyncFlowBaseContext, String logFileName, String LogDetailName, String url, Req req, Class<Res> resClass) {
        Res res = post(url, req, resClass);
        AsyncFlowCommon_Log.AddAsyncFlowDetailLog(asyncFlowBaseContext, logFileName, LogDetailName, req, res, true);
        return res;
    }

    /**
     * 异步流post 请求【接口会自动记录日志到异步流中】
     *
     * @param asyncFlowBaseContext 上下文
     * @param logFileName          文件名称
     * @param LogDetailName        日志描述
     * @param url                  地址
     * @param req                  请求
     * @param <Req>                请求类型
     * @return 具体返回
     */
    public static <Req, Res> Res asyncFlowPost(AsyncFlowBaseContext asyncFlowBaseContext, String logFileName, String LogDetailName, String url, Req req, TypeReference<Res> type) {
        String res = post(url, req, String.class);
        Res resObj = null;
        try {
            resObj = JSON.parseObject(res, type);
        } catch (Exception ex) {
            String msg = AsyncFlowSendMsg.buildErrorMsg(asyncFlowBaseContext.getAsyncFlowRequest(AsyncFlowRequest.class), ex, logFileName, asyncFlowBaseContext.getAsyncFlowInfo());
            AsyncFlowSendMsg.sendQYWXMsg(msg, asyncFlowBaseContext.getAsyncFlowInfo().getFlowMaintainName());
            AsyncFlowCommon_Log.AddAsyncFlowDetailLog(asyncFlowBaseContext, logFileName, LogDetailName, req, res, true);
            return null;
        }
        AsyncFlowCommon_Log.AddAsyncFlowDetailLog(asyncFlowBaseContext, logFileName, LogDetailName, req, resObj, true);
        return resObj;
    }

    /**
     * 异步流get 请求【接口会自动记录日志到异步流中】
     *
     * @param asyncFlowBaseContext 上下文
     * @param logFileName          文件名称
     * @param LogDetailName        日志描述
     * @param url                  地址
     * @param req                  请求键值对
     * @param resClass             返回实体
     * @param <Res>                返回实体
     * @return 返回
     */
    public static <Res> Res asyncFlowGet(AsyncFlowBaseContext asyncFlowBaseContext, String logFileName, String LogDetailName, String url, Map<String, Object> req, Class<Res> resClass) {
        Res res = get(url, req, resClass);
        AsyncFlowCommon_Log.AddAsyncFlowDetailLog(asyncFlowBaseContext, logFileName, LogDetailName, req, res, true);
        return res;
    }

}
